package com.txtsqlclient.ui.helper;

import java.io.BufferedReader;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * This class is required to capture user's input. Provides ways to capture user
 * input, securely and with masking. Code copied from:
 * http://forum.java.sun.com/thread.jspa?forumID=9&threadID=490728
 * 
 * @author spadda
 */
public class UserInputCapturer {

	/**
	 * Refer to this page for more details:
	 * http://forum.java.sun.com/thread.jspa?forumID=9&threadID=490728 <br>
	 * Note: might not work on Mac
	 * 
	 * @param prompt
	 * @return the password in the form of a char[]. Reset the char[] after
	 *         encrypting any secure details.
	 */
	public static final char[] getSecureMaskedLine(final String prompt)
			throws IOException {
		// password holder
		final CharArrayWriter caw = getMaskedInput(prompt);
		final char[] password = caw.toCharArray();
		// The buffer can be erased char-by-char to avoid breach of any secure
		// data in the memory.
		caw.close();
		return password;
	}

	/**
	 * This method is required to read the user's input while applying masking.
	 * 
	 * @param prompt
	 * @return a Writer object, from which the char array, or the string can be
	 *         obtained. Please make sure to close the stream.
	 */
	private static CharArrayWriter getMaskedInput(final String prompt)
			throws IOException {
		final CharArrayWriter caw = new CharArrayWriter();
		// password holder
		final MaskingThread maskingthread = new MaskingThread(prompt);
		final Thread thread = new Thread(maskingthread);
		thread.start();
		// block until enter is pressed
		while (true) {
			char c = (char) System.in.read();
			// assume enter pressed, stop masking
			maskingthread.stopMasking();
			if (c == '\r') {
				c = (char) System.in.read();
				if (c == '\n') {
					break;
				} else {
					continue;
				}
			} else if (c == '\n') {
				break;
			} else {
				// store the password
				caw.append(c);
			}
		}
		return caw;
	}

	public static final String getLine(final String prompt) throws IOException {
		System.out.print(prompt);
		final BufferedReader br = new BufferedReader(new InputStreamReader(
				System.in));
		String line = null;
		line = br.readLine();
		return line;
	}
}
